﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Web.Script.Serialization;
using System.Reflection;

/// <summary>
/// JSONHelper 的摘要说明
/// </summary>
/// 
namespace ReportFlat.Common
{
    //链式操作的Dictionary,加多个key:values时用到
    public class JSONDic : Dictionary<string, object>
    {
        public JSONDic AddF(string key, object value)
        {
            this.Add(key, value);
            return this;
        }

        public string ToSucJson()
        {
            return JSONHelper.ToSucJson(this);
        }

        public string ToErrorJson(string code = "400")
        {
            return JSONHelper.ToErroJson(this, code);
        }
    }

    public class JSONHelper
    {
        public static JSONDic AddF(string key, object value)
        {
            JSONDic j = new JSONDic();
            j.Add(key, value);
            return j;
        }
        //对应JSON的singleInfo成员
        public static readonly string SuccessJson = "{\"success\":true}";

        //反序列
        public static T ToObject<T>(string jsonStr)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Deserialize<T>(jsonStr);
        }

        //反序列
        public static IList<Dictionary<string, object>> ToList(string jsonStr)
        {
            return JSONHelper.ToObject<IList<Dictionary<string, object>>>(jsonStr);
        }

        //反序列
        public static Dictionary<string, object> ToDictionary(string jsonStr)
        {
            return JSONHelper.ToObject<Dictionary<string, object>>(jsonStr);
        }

        public static string GetString(string jsonStr, string key)
        {
            object value = JSONHelper.GetObject(jsonStr, key);
            return value == null ? "" : value.ToString();
        }

        public static object GetObject(string jsonStr, string key)
        {
            if (string.IsNullOrEmpty(jsonStr))
            {
                return null;
            }
            Dictionary<string, object> d = JSONHelper.ToObject<Dictionary<string, object>>(jsonStr);
            if (d.ContainsKey(key))
            {
                return d[key];
            }
            return null;
        }

        //简单的成功json
        public static string ToSucJson(string key, object value)
        {
            Dictionary<string, Object> resultDict = new Dictionary<string, Object>();
            resultDict.Add("success", true);
            resultDict.Add("code", 200);
            resultDict.Add(key, value);
            return JSONHelper.ToJSON(resultDict);
        }
        public static string ToSucJson(Dictionary<string, Object> dict)
        {
            dict.Add("success", true);
            dict.Add("code", 200);
            return JSONHelper.ToJSON(dict);
        }

        //简单的失败json
        public static string ToErroJson(string erroMsg, string code = "400")
        {
            Dictionary<string, Object> resultDict = new Dictionary<string, Object>();
            resultDict.Add("success", false);
            resultDict.Add("code", code);
            resultDict.Add("msg", erroMsg);
            return JSONHelper.ToJSON(resultDict);
        }

        public static string ToErroJson(Dictionary<string, Object> dict, string code = "400")
        {
            dict.Add("success", false);
            dict.Add("code", code);
            return JSONHelper.ToJSON(dict);
        }

        //object全部字段json化
        public static string ToJSON(object obj)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(obj);
        }

        //List全部字段json化---- extjs专用
        public static string ToSucJson(IList list, int rowCount)
        {
            //泛型必须强转类型(IList)后传进来，否则json会多一层[] ---- 神奇了！！！
            Dictionary<string, Object> resultDict = new Dictionary<string, Object>();
            resultDict.Add("success", true);
            resultDict.Add("code", 200);
            resultDict.Add("totalCount", rowCount);
            resultDict.Add("data", list);
            return JSONHelper.ToJSON(resultDict);
        }

        public static string ToSucJson(IList list, int rowCount, object sumData)
        {
            //泛型必须强转类型(IList)后传进来，否则json会多一层[] ---- 神奇了！！！
            Dictionary<string, Object> resultDict = new Dictionary<string, Object>();
            resultDict.Add("success", true);
            resultDict.Add("code", 200);
            resultDict.Add("totalCount", rowCount);
            resultDict.Add("data", list);
            resultDict.Add("sumData", sumData);
            return JSONHelper.ToJSON(resultDict);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="fields"></param>
        /// TODO：如果fields=* ,代表全部
        /// <returns></returns>
        public static Dictionary<string, Object> CustomObj(Object orgObj, string fieldNames, Action<Dictionary<string, Object>, Object> extendFn = null)
        {
            Type type = orgObj.GetType();
            string[] fields = null;
            if (string.IsNullOrEmpty(fieldNames) || fieldNames == "*")
            {
                fields = allFields(type);
            }
            else
            {
                fields = fieldNames.Split(',');
            }
            Dictionary<string, Object> newObj = new Dictionary<string, object>();
            foreach (string field in fields)
            {
                newObj.Add(field, type.GetField(field).GetValue(orgObj));
            }
            extendFn(newObj, orgObj);
            return newObj;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="fields"></param>
        /// <param name="extendFn"></param>
        /// <returns></returns>
        public static IList<Dictionary<string, Object>> CustomList(IList orgList, string fieldNames, Action<Dictionary<string, Object>, Object> extendFn = null)
        {
            IList<Dictionary<string, Object>> result = new List<Dictionary<string, Object>>();
            if (orgList == null || orgList.Count == 0)
            {
                return result;
            }
            //为了加快速度，反射在这里做委托
            Type type = orgList[0].GetType();
            string[] fields = null;
            if (string.IsNullOrEmpty(fieldNames) || fieldNames == "*")
            {
                fields = allFields(type);
            }
            else
            {
                fields = fieldNames.Split(',');
            }
            IList<PropertyInfo> props = new List<PropertyInfo>();
            foreach (string field in fields)
            {
                props.Add(type.GetProperty(field));
            }
            //循环取值
            foreach (Object orgObj in orgList)
            {
                Dictionary<string, Object> newObj = new Dictionary<string, object>();
                foreach (PropertyInfo prop in props)
                {
                    newObj.Add(prop.Name, prop.GetValue(orgObj));
                }
                if (extendFn != null)
                {
                    extendFn(newObj, orgObj);
                }
                result.Add(newObj);
            }
            return result;
        }

        private static String[] allFields(Type type)
        {
            List<string> list = new List<string>();
            foreach (var pro in type.GetProperties())
            {
                var attr = pro.GetCustomAttribute(typeof(ScriptIgnoreAttribute));
                if (attr==null) {
                    list.Add(pro.Name);
                }
            }
            return list.ToArray();
        }
    }
}
